package com.accelstack.cmp.service;

import com.accelstack.cmp.entity.GpuModel;
import com.accelstack.cmp.repository.GpuModelRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * GPU型号Service
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class GpuModelService {
    
    private final GpuModelRepository gpuModelRepository;
    
    @Transactional
    public GpuModel create(GpuModel gpuModel) {
        return gpuModelRepository.save(gpuModel);
    }
    
    @Transactional
    public GpuModel update(GpuModel gpuModel) {
        return gpuModelRepository.save(gpuModel);
    }
    
    @Transactional
    public void deleteById(Long id) {
        gpuModelRepository.deleteById(id);
    }
    
    public Optional<GpuModel> findById(Long id) {
        return gpuModelRepository.findById(id);
    }
    
    public List<GpuModel> findAll() {
        return gpuModelRepository.findAll();
    }
    
    public Page<GpuModel> findAll(Pageable pageable) {
        return gpuModelRepository.findAll(pageable);
    }
    
    /**
     * 批量删除GPU型号
     */
    @Transactional
    public void batchDelete(List<Long> ids) {
        gpuModelRepository.deleteAllById(ids);
    }
    
    /**
     * 根据厂商查询GPU型号
     */
    public List<GpuModel> findByVendor(String vendor) {
        return gpuModelRepository.findByVendor(vendor);
    }
    
    /**
     * 获取所有厂商列表
     */
    public List<String> findAllVendors() {
        return gpuModelRepository.findAllDistinctVendors();
    }
    
    /**
     * 根据名称搜索GPU型号
     */
    public List<GpuModel> searchByName(String keyword) {
        return gpuModelRepository.findByNameContainingIgnoreCase(keyword);
    }
    
    /**
     * 根据显存大小查询GPU型号
     */
    public List<GpuModel> findByVramGb(Integer vramGb) {
        return gpuModelRepository.findByVramGb(vramGb);
    }
    
    /**
     * 根据显存范围查询GPU型号
     */
    public List<GpuModel> findByVramRange(Integer minVram, Integer maxVram) {
        return gpuModelRepository.findByVramGbBetween(minVram, maxVram);
    }
    
    /**
     * 批量创建GPU型号
     */
    @Transactional
    public List<GpuModel> batchCreate(List<GpuModel> gpuModels) {
        return gpuModelRepository.saveAll(gpuModels);
    }
    
    /**
     * 获取GPU型号统计信息
     */
    public Map<String, Object> getStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总数
        long totalCount = gpuModelRepository.count();
        statistics.put("totalCount", totalCount);
        
        // 按厂商统计
        List<GpuModel> allModels = gpuModelRepository.findAll();
        Map<String, Long> vendorStats = allModels.stream()
                .filter(gpu -> gpu.getVendor() != null)
                .collect(Collectors.groupingBy(GpuModel::getVendor, Collectors.counting()));
        statistics.put("vendorStatistics", vendorStats);
        
        // 按显存大小统计
        Map<Integer, Long> vramStats = allModels.stream()
                .filter(gpu -> gpu.getVramGb() != null)
                .collect(Collectors.groupingBy(GpuModel::getVramGb, Collectors.counting()));
        statistics.put("vramStatistics", vramStats);
        
        // 平均显存大小
        OptionalDouble avgVram = allModels.stream()
                .filter(gpu -> gpu.getVramGb() != null)
                .mapToInt(GpuModel::getVramGb)
                .average();
        if (avgVram.isPresent()) {
            statistics.put("averageVramGb", String.format("%.2f", avgVram.getAsDouble()));
        }
        
        // 最大显存
        Optional<Integer> maxVram = allModels.stream()
                .filter(gpu -> gpu.getVramGb() != null)
                .map(GpuModel::getVramGb)
                .max(Integer::compare);
        maxVram.ifPresent(vram -> statistics.put("maxVramGb", vram));
        
        // 最小显存
        Optional<Integer> minVram = allModels.stream()
                .filter(gpu -> gpu.getVramGb() != null)
                .map(GpuModel::getVramGb)
                .min(Integer::compare);
        minVram.ifPresent(vram -> statistics.put("minVramGb", vram));
        
        return statistics;
    }
}

